package com.baidu.jiuhao.es.service;

import com.baidu.jiuhao.es.req.DocumentReq;
import com.baidu.jiuhao.es.util.EsUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class DocumentSearchService {

    private final RestHighLevelClient esClient;

    @Value("${elasticsearch.index}")
    private String indexName;


    public List<Map<String, Object>> searchDocuments(DocumentReq request) throws IOException {
        // 1. 构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 2. 处理嵌套权限标签查询（tags是nested类型）
        BoolQueryBuilder nestedBool = QueryBuilders.boolQuery();
        addTermsIfNotEmpty(nestedBool, "tags.area", request.getArea());
        addTermsIfNotEmpty(nestedBool, "tags.product", request.getProduct());
        addTermsIfNotEmpty(nestedBool, "tags.language", request.getLanguage());
        addTermsIfNotEmpty(nestedBool, "tags.secret_level", request.getSecretLevel());
        addTermsIfNotEmpty(nestedBool, "tags.channel", request.getChannel());
        addTermsIfNotEmpty(nestedBool, "tags.object", request.getObject());
        addTermsIfNotEmpty(nestedBool, "tags.business_attribute", request.getBusinessAttribute());

        // 修正：使用ScoreMode.NONE作为评分模式
        NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery(
                "tags",
                nestedBool,
                ScoreMode.None
        );

        // 3. 动态排序（根据sortType选择排序字段）
        String sortField = getSortField(request.getSortType());
        sourceBuilder.sort(sortField, SortOrder.DESC);

        // 4. 设置分页（取前10条）
        sourceBuilder.from(0).size(10);

        // 5. 组装完整查询
        SearchRequest searchRequest = new SearchRequest(indexName);
        searchRequest.source(sourceBuilder.query(nestedQuery));

        // 打印 DSL
        log.info("----- Generated DSL -----");
        EsUtils.printPrettyDSL(sourceBuilder.toString());

        // 6. 执行查询并解析结果
        SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
        return  EsUtils.parseSearchResponse(response);
    }

    // 修改点2：适配List<String>的工具方法
    private void addTermsIfNotEmpty(BoolQueryBuilder boolQuery, String field, List<String> values) {
        if (values != null && !values.isEmpty()) {
            // 使用termsQuery匹配列表中任意一个值
            boolQuery.must(QueryBuilders.termsQuery(field, values));
        }
    }

    // 工具方法：根据sortType获取排序字段
    private String getSortField(String sortType) {
        switch (sortType.toLowerCase()) {
            case "day":
                return "daily_view_count";
            case "week":
                return "weekly_view_count";
            case "month":
                return "monthly_view_count";
            default:
                throw new IllegalArgumentException("无效的排序类型，仅支持day/week/month");
        }
    }


}
